package com.soul.dubbo.api.mongo;

import com.soul.model.eums.CommentType;
import com.soul.model.mongo.Comment;
import com.soul.model.mongo.Movement;
import com.soul.model.mongo.MovementTimeLine;
import com.soul.model.mongo.Praise;
import com.soul.model.vo.PageResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboService;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.FindAndModifyOptions;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.mongodb.core.query.UpdateDefinition;

import java.util.List;

/**
 * @author mdoya
 * @version 1.0
 * @description:
 */
@Slf4j
@DubboService
public class CommentApiImpl implements CommentApi {

    @Autowired
    private MongoTemplate mongoTemplate;

    /**
     * 圈子 - 评论列表
     *
     * @param movementId 动态id
     * @param page       每页码数
     * @param pagesize   每页条数
     * @return PageResult<Comment>
     */
    @Override
    public PageResult<Comment> findPageComment(String movementId, Long page, Long pagesize) {
        // 1. 查询总条数
        Query query = new Query();
        query.addCriteria(Criteria.where("publishId").is(new ObjectId(movementId)).and("commentType").is(CommentType.COMMENT.getType()));
        long count = mongoTemplate.count(query, Comment.class);

        // 2. 查询评论分页
        query.skip((page - 1) * pagesize).limit(pagesize.intValue());
        query.with(Sort.by(Sort.Direction.DESC,"created"));
        List<Comment> commentList = mongoTemplate.find(query, Comment.class);

        return new PageResult<>(page,pagesize,count,commentList);
    }

    /**
     * 圈子 - 新增评论
     *
     * @param comment 评论对象
     */
    @Override
    public Integer addComment(Comment comment) {
        // 1. 新增评论
        long newTime = System.currentTimeMillis();
        comment.setCreated(newTime);
        Movement movement = mongoTemplate.findById(comment.getPublishId(), Movement.class);
        comment.setPublishUserId(movement.getUserId());
        mongoTemplate.insert(comment);
        // 2. 更新 评论 条数 后返回总条数
        Query query = new Query();
        query.addCriteria(Criteria.where("id").is(comment.getPublishId()));
        Update update = new Update(); // 要修改的字段
        update.inc(getCollName(comment.getCommentType()),1); // 字段自增1
        FindAndModifyOptions findAndModifyOptions = new FindAndModifyOptions();
        findAndModifyOptions.returnNew(true); // 修改后返回值
        Movement movementMongoTemplate = mongoTemplate.findAndModify(query, update, findAndModifyOptions, Movement.class);
        return movementMongoTemplate.statisCount(comment.getCommentType());
    }

    /**
     * 圈子 - 取消点赞
     *
     * @param comment 评论对象
     */
    @Override
    public Integer deleteComment(Comment comment) {
        // 1. 根据条件删除评论记录
        Query query = new Query();
        query.addCriteria(Criteria.where("publishId").is(comment.getPublishId()).and("commentType").is(comment.getCommentType()).and("userId").is(comment.getUserId()));
        mongoTemplate.remove(query,Comment.class);
        // 2. 根据条件更新评论条数
        Query query2 = new Query();
        query2.addCriteria(Criteria.where("id").is(comment.getPublishId()));
        Update update = new Update(); // 要修改的字段
        update.inc(getCollName(comment.getCommentType()),-1); // 字段自增1
        FindAndModifyOptions findAndModifyOptions = new FindAndModifyOptions();
        findAndModifyOptions.returnNew(true); // 修改后返回值
        Movement movementMongoTemplate = mongoTemplate.findAndModify(query2, update, findAndModifyOptions, Movement.class);
        return movementMongoTemplate.statisCount(comment.getCommentType());
    }

    /**
     * 评论点赞
     *
     * @param praise
     * @return
     */
    @Override
    public Integer commentLike(Praise praise) {
        long nowTime = System.currentTimeMillis();
        Comment comment = mongoTemplate.findById(praise.getPublishId(), Comment.class);
        if (comment != null){
            praise.setPublishUserId(comment.getUserId());
            praise.setCreated(nowTime);
            praise.setUpdated(nowTime);
            mongoTemplate.insert(praise);
        }
        Update update = new Update();
        System.err.println("数据类型 = " + getCollName(praise.getCommentType())); // likeCount
        update.inc(getCollName(praise.getCommentType()),1);
        FindAndModifyOptions findAndModifyOptions = new FindAndModifyOptions();
        findAndModifyOptions.returnNew(true);
        Query query = new Query();
        query.addCriteria(Criteria.where("id").is(praise.getPublishId()));
        Comment c = mongoTemplate.findAndModify(query, update, findAndModifyOptions, Comment.class);
        return c.getLikeCount();
    }

    /**
     * 评论取消点赞
     *
     * @param praise
     * @return
     */
    @Override
    public Integer commentDislike(Praise praise) {
        Query query = new Query();
        query.addCriteria(Criteria.where("publishId").is(praise.getPublishId()).and("commentType").is(praise.getCommentType()));
        Comment comment = mongoTemplate.findById(praise.getPublishId(), Comment.class);
        if (comment != null){
            mongoTemplate.remove(query,Praise.class);
        }
        Update update = new Update();
        update.inc(getCollName(praise.getCommentType()),-1);
        FindAndModifyOptions findAndModifyOptions = new FindAndModifyOptions();
        findAndModifyOptions.returnNew(true); // 返回修改后数量
        Query query2 = new Query();
        query2.addCriteria(Criteria.where("id").is(praise.getPublishId()));
        Comment andModify = mongoTemplate.findAndModify(query2, update, findAndModifyOptions, Comment.class);
        return andModify.getLikeCount();
    }

    /**
     *  根据类型自动获取字段类型
     * @param commentType
     * @return
     */
    private String getCollName(int commentType){
        if(CommentType.LIKE.getType() == commentType){
            return "likeCount";
        }else if(CommentType.COMMENT.getType() == commentType){
            return "commentCount";
        }else{
            return "loveCount";
        }
    }
}
